#include "filereader.h"
#include <QDir>
#include <QMessageBox>

FileReader::FileReader(QTcpSocket *socket, const QString &saveFileName, QObject *parent)
    :QObject(parent), m_socket(socket),m_saveFileName(saveFileName)
{
    m_totalFilesSize = 0;
    m_totalBytesRead = 0;
    m_currentFileSize = 0;
    m_currentBytesRead = 0;
    m_totalFilesNumber = 0;
    m_readFilesNumber = 0;
    m_readState = READ_FILESINFO;
    //连接信号
    connect(m_socket, &QTcpSocket::disconnected, m_socket, &QTcpSocket::deleteLater);
    connect(m_socket, &QIODevice::readyRead, this, &FileReader::onReadyRead);
}

void FileReader::readFail(const QString &failInfo)
{
    m_socket->close();
    QMessageBox::warning(nullptr, "错误", failInfo);
}

void FileReader::readOk()
{
    m_socket->close();
    QMessageBox::information(nullptr, "提示",
                             QString("接收文件: %1 完成!一共接收%2 byt数据, %3 个文件")
                             .arg(m_readFileName)
                             .arg(m_totalFilesSize)
                             .arg(m_totalFilesNumber));
}


void FileReader::onReadyRead()
{
    while(m_socket->bytesAvailable()){
        switch (m_readState) {
            case READ_FILESINFO:
            {
                //读取总的接受信息头
                FilesInfo filesInfo;
                m_socket->read((char*)&filesInfo, sizeof(filesInfo));
                m_totalFilesSize = filesInfo.m_filesSize;
                m_totalFilesNumber = filesInfo.m_filesNumber;
                //读取验证信息
                QByteArray passid = m_socket->read(filesInfo.m_passidSize);
                //改变状态
                m_readState = READ_HEAD;
                qDebug() << QString("passid = %1, 总大小为 %2, 总文件数为 %3")
                            .arg(QString(passid)).arg(m_totalFilesSize).arg(m_totalFilesNumber);
            }
            //读取文件头
            case READ_HEAD:
            {
                if(m_socket->bytesAvailable() >= sizeof(m_head)){
                    m_socket->read((char*)&m_head, sizeof(m_head));
                    if(m_head.m_fileType != FileHead::TYPE_DIR &&
                            m_head.m_fileType != FileHead::TYPE_FILE){
                        readFail("遇到不能识别的文件头类型");
                    }
                    m_currentFileSize = m_head.m_fileContentSize;
                    m_currentBytesRead = 0;
                    m_readState = READ_NAME;
                }
            }
                break;
            //读取文件名
            case READ_NAME:
            {
                if(m_socket->bytesAvailable() >= m_head.m_fileNameSize){
                    QString fileName(m_socket->read(m_head.m_fileNameSize));
                    if(m_head.m_fileType == FileHead::TYPE_DIR){
                        QDir dir;
                        if(!dir.mkpath(m_saveFileName + "/" + fileName)){
                            readFail(QString("创建文件夹%1 失败").arg(m_saveFileName + "/" + fileName));
                            return;
                        }
                        if(++m_readFilesNumber == m_totalFilesNumber){
                            readOk();
                            return;
                        }
                        m_readState = READ_HEAD;
                    }
                    else{
                        m_file.setFileName(m_saveFileName + "/" + fileName);
                        if(!m_file.open(QIODevice::WriteOnly)){
                            readFail(QString("创建文件%1 失败").arg(m_saveFileName + "/" + fileName));
                            return;
                        }
                        m_readState = READ_CONTENT;
                    }
                    //保存第一个读取的文件名
                    if(m_readFileName.isEmpty()){
                        m_readFileName = fileName;
                    }
                }
            }
                break;
            //读取文件内容
            case READ_CONTENT:
            {
                int readSize = qMin(m_socket->bytesAvailable(), m_currentFileSize - m_currentBytesRead);
                m_file.write(m_socket->read(readSize));
                m_currentBytesRead += readSize;
                m_totalBytesRead += readSize;
                if(m_currentBytesRead == m_currentFileSize){
                    m_file.close();
                    m_readState = READ_HEAD;
                    if(++m_readFilesNumber == m_totalFilesNumber){
                        readOk();
                        return;
                    }
                }
            }
                break;
            //以防万一
            default:
                readFail("readyRead()遇到不能识别状态");
                break;
        }
    }
}

